package com.ruoyi.subject.service.impl;

import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.subject.domain.QbSubject;
import com.ruoyi.subject.domain.SubjectRule;
import com.ruoyi.subject.mapper.QbSubjectItemMapper;
import com.ruoyi.subject.mapper.QbSubjectMapper;
import com.ruoyi.subject.service.IQbSubjectService;
import com.ruoyi.subject.util.QbSubjectUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;

/**
 * 题目Service业务层处理
 *
 * @author lzhj
 * @date 2021-01-20
 */
@Service
public class QbSubjectServiceImpl implements IQbSubjectService {

    private static Logger logger = LoggerFactory.getLogger(QbSubjectServiceImpl.class);

    @Autowired
    private QbSubjectMapper qbSubjectMapper;

    @Autowired
    private QbSubjectItemMapper qbSubjectItemMapper;

    @Autowired
    private RedisCache redisCache;

    /**
     * 项目启动时，初始化抽题规则到缓存
     */
//    @PostConstruct
    @Override
    public void initSubjectRule() {
        List<SubjectRule> subjectRules = qbSubjectMapper.selectSubjectRule();
        logger.info("初始化抽题规则到缓存");
        if (CollectionUtils.isNotEmpty(subjectRules)) {
            Map<String, List<SubjectRule>> ruleMap = subjectRules.stream().collect(Collectors.groupingBy(SubjectRule::getCategory));
            for (Map.Entry<String, List<SubjectRule>> entry : ruleMap.entrySet()) {
                String key = QbSubjectUtil.getSubjectRuleCacheKey(entry.getKey());
                List<SubjectRule> value = entry.getValue();
                logger.info("抽题规则key：" + key + "\tvalue->size：" + value.size());
                redisCache.setCacheObject(key, value);
            }
        }
    }

    /**
     * 初始化题目id，按题库类型，类别，题型 分类
     */
//    @PostConstruct
    public void initSubjectTypeData() {
        initSubjectTypeCacheData();
    }

    /**
     * 初始化题目id，按题库类型，类别，题型 分类
     */
    @Override
    public void initSubjectTypeCacheData() {
        List<QbSubject> subjectList = qbSubjectMapper.selectAllSubject();
        logger.info("初始化题目id，按题库类型，类别，题型  分类");
        if (CollectionUtils.isNotEmpty(subjectList)) {
            Map<String, List<QbSubject>> subjectMap = subjectList.stream().collect(Collectors.groupingBy(e -> QbSubjectUtil.getSubjectTypeCacheKey(e.getCategory(), e.getSubClass(), e.getQueType()), TreeMap::new, Collectors.toList()));
//            Map<String, List<QbSubject>> subjectMap = subjectList.stream().collect(Collectors.groupingBy(e -> e.getCategory() + ":" + e.getSubClass() + ":" + e.getQueType()));
            for (Map.Entry<String, List<QbSubject>> entry : subjectMap.entrySet()) {
                String key = entry.getKey();
                List<QbSubject> value = entry.getValue();
                logger.info("按题库类型，类别，题型  分类key：" + key + "\tvalue->size：" + value.size());
//                System.out.println(subjectIdList);
                redisCache.setCacheObject(key, value);
            }
        }
    }

    @Override
    public List<QbSubject> querySubjectByName(String search, String subType, int curPage, int pageSize) {
        int startSize = (curPage - 1) * pageSize;
        List<QbSubject> subjectList = qbSubjectMapper.querySubjectByName(search, subType, startSize, pageSize);
        return subjectList;
    }

    @Override
    public int querySubjectCountByName(String search, String subType, int curPage, int pageSize) {
        return qbSubjectMapper.querySubjectCountByName(search, subType);
    }

    @Override
    public List<QbSubject> selectSubjectByCategoryAnsQueType(String category, String subClass) {
        return qbSubjectMapper.selectSubjectByCategoryAnsQueType(category, subClass);
    }

    /**
     * 查询题目
     *
     * @param id 题目ID
     * @return 题目
     */
    @Override
    public QbSubject selectQbSubjectById(Long id) {
        return qbSubjectMapper.selectQbSubjectById(id);
    }

    /**
     * 查询题目列表
     *
     * @param qbSubject 题目
     * @return 题目
     */
    @Override
    public List<QbSubject> selectQbSubjectList(QbSubject qbSubject) {
        return qbSubjectMapper.selectQbSubjectList(qbSubject);
    }

    /**
     * 新增题目
     *
     * @param qbSubject 题目
     * @return 结果
     */
    @Override
    public int insertQbSubject(QbSubject qbSubject) {
        qbSubject.setCreateTime(DateUtils.getNowDate());
        return qbSubjectMapper.insertQbSubject(qbSubject);
    }

    /**
     * 修改题目
     *
     * @param qbSubject 题目
     * @return 结果
     */
    @Override
    public int updateQbSubject(QbSubject qbSubject) {
        qbSubject.setUpdateTime(DateUtils.getNowDate());
        return qbSubjectMapper.updateQbSubject(qbSubject);
    }

    /**
     * 批量删除题目
     *
     * @param ids 需要删除的题目ID
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteQbSubjectByIds(Long[] ids) {
        qbSubjectItemMapper.deleteQbSubjectItemBySubjectIds(ids);
        return qbSubjectMapper.deleteQbSubjectByIds(ids);
    }

    /**
     * 删除题目信息
     *
     * @param id 题目ID
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteQbSubjectById(Long id) {
        qbSubjectItemMapper.deleteQbSubjectItemBySubjectIds(new Long[]{id});
        return qbSubjectMapper.deleteQbSubjectById(id);
    }

    /**
     * 更新按题库类型，类别，题型 分类cache的数据
     *
     * @param category
     * @param subClass
     * @param queType
     */
    @Override
    public void updateSubjectTypeCache(String category, String subClass, String queType) {
        if (StringUtils.isBlank(category) || StringUtils.isBlank(subClass) || StringUtils.isBlank(queType)) {
            return;
        }
        List<Long> subjectIdList = qbSubjectMapper.selectAllSubjectId(category, subClass, queType);
        String key = QbSubjectUtil.getSubjectTypeCacheKey(category, subClass, queType);
        logger.info("按题库类型，类别，题型  分类key：" + key + "\tvalue->size：" + subjectIdList.size());
        redisCache.setCacheObject(key, subjectIdList);
    }
}
